package com.gestocasa.view.dialogs;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public abstract class DialogBase extends JDialog {

	private JButton okButton;
	private JButton cancelButton;
	
	private boolean cancel;
	private boolean needInit;
	
	public DialogBase(Dialog parent, String title, boolean modal) {
		super(parent, title, modal);
		init();
		setLocationRelativeTo(parent);
	}
	
	public DialogBase(Frame parent, String title, boolean modal) {
		super(parent, title, modal);
		init();
		setLocationRelativeTo(parent);
	}
	
	private void init() {
		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		
		okButton = new JButton("Aceptar");
		okButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				doOK();
			}
		});
		
		cancelButton = new JButton("Cancelar");
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				doCancel();
			}
		});
		
		installKeyListeners();
		
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				doCancel();
			}
		});
		
		needInit = true;
	}
	
	private void installKeyListeners() {
		InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		inputMap.put(KeyStroke.getKeyStroke("ESCAPE"), "ESCAPE");
		getRootPane().getActionMap().put("ESCAPE", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				onKeyEscape();
			}
		});
		
		inputMap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		inputMap.put(KeyStroke.getKeyStroke("DELETE"), "DELETE");
		getRootPane().getActionMap().put("DELETE", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				onKeyDelete();
			}
		});
		
		inputMap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		inputMap.put(KeyStroke.getKeyStroke("INSERT"), "INSERT");
		getRootPane().getActionMap().put("INSERT", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				onKeyInsert();
			}
		});
		
		inputMap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		inputMap.put(KeyStroke.getKeyStroke("ENTER"), "ENTER");
		getRootPane().getActionMap().put("ENTER", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				onKeyEnter();
			}
		});
	}
	
	private void makeMainPanel() {
		JPanel buttonsPanel = new JPanel();
		buttonsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
		buttonsPanel.add(Box.createHorizontalGlue());
		buttonsPanel.add(okButton);
		buttonsPanel.add(Box.createRigidArea(new Dimension(10, 0)));
		buttonsPanel.add(cancelButton);
		buttonsPanel.add(Box.createHorizontalGlue());
		
		JPanel globalPanel = makePanels();
		JPanel mainPanel = new JPanel();
		mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		mainPanel.setLayout(new BorderLayout());
		if(globalPanel != null) {
			mainPanel.add(globalPanel, BorderLayout.CENTER);
		}
		else {
			mainPanel.add(new JPanel(), BorderLayout.CENTER);
		}
		mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
		
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(mainPanel, BorderLayout.CENTER);
	}
	
	private void centerParent() {
		int x = 0;
		int y = 0;
		int offset;
		Container myParent = getParent();
		
		if(myParent != null) {
			Point topLeft = myParent.getLocationOnScreen();
			Dimension parentSize = myParent.getSize();
			Dimension mySize = getSize();
			
			if (parentSize.width > mySize.width) { 
				x = ((parentSize.width - mySize.width)/2) + topLeft.x;
			}
			else {
				offset = mySize.width - parentSize.width;
				if(topLeft.x - (offset / 2.0) < 0)
					x = topLeft.x;
				else 
					x = (int)(topLeft.x - (offset / 2.0));
			}
			
			if (parentSize.height > mySize.height) { 
				y = ((parentSize.height - mySize.height)/2) + topLeft.y;
			}
			else {
				offset = mySize.height - parentSize.height;
				if(topLeft.y - (offset / 2.0) < 0)
					y = topLeft.y;
				else
					y = (int)(topLeft.y - (offset / 2.0));
			}
		}
		
		setLocation (x, y);
		requestFocus();
	}  
	
	protected void doOK() {
		setVisible(false);
	}
	
	protected void doCancel() {
		cancel = true;
		setVisible(false);
	}
	
	protected abstract void initComponents();
	protected abstract JPanel makePanels();
	protected abstract Dimension getDefaultSize();
	
	protected void onKeyEscape() {
		doCancel();
	}
	
	protected void onKeyEnter() {}
	protected void onKeyDelete() {}
	protected void onKeyInsert() {}
	
	public boolean isCanceled() {
		return cancel;
	}
	
	@Override
	public void setVisible(boolean b) {
		if(needInit == true) {
			initComponents();
			makeMainPanel();
			
			setPreferredSize(getDefaultSize());
			pack();
			
			centerParent();
			needInit = false;
		}
		super.setVisible(b);
	}
}
